package evolution.operation.mutation;

import evolution.individual.Individual;
import evolution.problem.ProblemConstraints;
import evolution.random.RandomGenerator;

public abstract class AbstractMutation implements MutationStrategy {

	protected double probability = 0.05;
	protected RandomGenerator randomGenerator;
	protected ProblemConstraints constraints;

	@Override
	public void mutate(Individual[] original) {
		for (int i = 0; i < original.length; i++) {
			double[] chromosome = original[i].getChromosome();
			boolean chromosomeModified = false;

			for (int j = 0; j < chromosome.length; j++) {
				if (randomGenerator.nextDouble() < probability) {
					chromosome[j] = generateValue();
					chromosomeModified = true;
				}
			}

			if (chromosomeModified) {
				original[i].setFitness(original[i].getFitnessFunction()
						.getValue(chromosome));
			}

		}
	}

	public abstract double generateValue();

	@Override
	public double getProbability() {
		return probability;
	}

	@Override
	public void setProbability(double probability) {
		this.probability = probability;
	}

	@Override
	public RandomGenerator getRandomGenerator() {
		return randomGenerator;
	}

	@Override
	public void setRandomGenerator(RandomGenerator randomGenerator) {
		this.randomGenerator = randomGenerator;
	}

	public ProblemConstraints getConstraints() {
		return constraints;
	}

	public void setConstraints(ProblemConstraints constraints) {
		this.constraints = constraints;
	}

}
